package org.hiberlyzer.impl;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hiberlyzer.DataColumn;
import org.hiberlyzer.DataSet;

public class JdbcDataSet implements DataSet
{
	private static final Logger LOG = Logger.getLogger(JdbcDataSet.class);
	private ResultSet resultSet;
	private List<DataColumn> columns = new ArrayList<DataColumn>();
	private Integer cachedRowCount = null;
	
	protected JdbcDataSet(ResultSet resultSet) 
	{
		this.resultSet = resultSet;
		try
		{
			ResultSetMetaData metadata = resultSet.getMetaData();
			for(int i = 1; i <= metadata.getColumnCount(); i++)
			{
				String columnClassName = metadata.getColumnClassName(i);
				String columnName = metadata.getColumnName(i);
				Class columnClass = Object.class;
				try
				{
					columnClass = Class.forName(columnClassName);
				}
				catch(ClassNotFoundException e)
				{
					LOG.warn("ResultSetMetaData gave columnClassName: " + columnClassName + 
							" for column " + columnName + ", but it couldn't be found.");
				}
				columns.add(new SimpleDataColumn(columnName, columnClass));
			}
		}
		catch (SQLException e)
		{
			LOG.error("Couldn't read ResultSetMetadata", e);
			throw new RuntimeException(e);
		} 
	}

	public List<DataColumn> getColumns()
	{
		return columns;
	}
	
	public int getResultCount()
	{
		if(cachedRowCount == null)
		{
			cachedRowCount = calculateRowCount();
		}
		return cachedRowCount;
	}

	private Integer calculateRowCount()
	{
		int count = 0;
		try
		{
			resultSet.first();
			while(!resultSet.isAfterLast())
			{
				count++;
				resultSet.next();
			}
		}
		catch (SQLException e)
		{
			System.err.println("Error trying to calculateRowCount");
			e.printStackTrace();
		}
		return count;
	}

	public Object getValue(int rowIndex, int columnIndex)
	{
		try
		{
			if(resultSet.getRow() != rowIndex + 1)
			{
				resultSet.absolute(rowIndex + 1);
			}
			Object value = resultSet.getObject(columnIndex + 1);
			if(null == value)
			{
				value = "NULL";
			}
			return value;
		}
		catch (SQLException e)
		{
			System.err.println("Exception caught trying to get value at: " + rowIndex + ", " + columnIndex);
			e.printStackTrace();
			return null;
		}
	}
}
